package com.nakaikensuke.SNE;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.content.Context;

import com.nakaikensuke.tools.ListBuilder;

public class DirEntryComposer implements Runnable {
	
	///	When a process finished, call back this method.
	public interface Callback {
		void finish(List<DirEntry> list, boolean isCanceled);
	}
	
	private String _path = null;
	private String _encode = null;
	private Callback _callback = null;
	private IconCacheManager _manager = null;
	
	public DirEntryComposer(
			Context context,
			String path,
			String encode,
			Callback callback) {
		_path = path;
		_encode = encode;
		_callback = callback;
		_manager = new IconCacheManager(context.getPackageManager());
	}
	
	@Override
	public void run() {
		///	Obtain some directory entries,
		///	and notify them to a host component.
		List<DirEntry> entries = ListBuilder.createList();
		EntriesIterator iterator = new EntriesIterator(_path, _encode);
		while(true) {
			if(Thread.interrupted()) {
				if(_callback != null)
					_callback.finish(entries, true);
				return;
			}

			DirEntry entry = iterator.next();
			if(entry == null)
				break;
			
			if(!entry.isDir()) {
				entry.setIcon(
						_manager.getIcon(_path + "/" + getFileName(entry)));
			}
			
			entries.add(entry);
		}
		
		///	Sort directory entries.
		Collections.sort(
				entries,
				new Comparator<DirEntry>() {
					@Override
					public int compare(DirEntry entry1, DirEntry entry2) {
						String name1 = getName(entry1);
						String name2 = getName(entry2);
						boolean dir1 = entry1.isDir();
						boolean dir2 = entry2.isDir();
						
						///	"." (current) entry is first.
						if(name1.equals("."))
							return -1;
						if(name2.equals("."))
							return 1;
						
						///	".." (parent) entry is second.
						if(name1.equals(".."))
							return -1;
						if(name2.equals(".."))
							return 1;
						
						///	a directory is ahead of file.
						if(dir1 && (!dir2))
							return -1;
						else if((!dir1) && dir2)
							return 1;
						
						///	Last, sort entries according to character code.
						return name1.compareToIgnoreCase(name2);
					}

					private String getName(DirEntry entry) {
						String name = entry.getShortName();
						if(name.equals(""))
							name = entry.getLongName();
						
						return name;
					}
				});
		
		///	Notify this list to Host component.
		if(_callback != null)
			_callback.finish(entries, false);
	}
	
	private String getFileName(DirEntry entry) {
		String name = entry.getLongName();
		if(name == null || name.equals(""))
			name = entry.getShortName();
		
		return name;
	}
}
